# coding: utf-8

from PySide6.QtCore import Qt
from PySide6.QtGui import QResizeEvent
from PySide6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout
from qfluentwidgets import BodyLabel, setFont, HorizontalSeparator, Slider, PrimaryPushButton, \
    FluentIcon as FIF, StateToolTip, InfoBar, TransparentToolButton, PlainTextEdit, MessageBox

from common import Icon, signalBus, TTSThread, TranslationDict, VoiceThread
from components import TTSCard, CardListWidget


class ConversionInterface(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.shortName = None

        self.horizontalLayout = QHBoxLayout(self)
        self.horizontalLayout_2 = QHBoxLayout()
        self.verticalLayout = QVBoxLayout()
        self.textEdit = PlainTextEdit(self)
        self.titleLabel = BodyLabel('语音列表', self)
        self.cardListWidget = CardListWidget(self)
        self.rateLabel = BodyLabel('语速(--rate=0%)', self)
        self.rateSlider = Slider(Qt.Orientation.Horizontal, self)
        self.volumeLabel = BodyLabel('音量(--volume=0%)', self)
        self.volumeSlider = Slider(Qt.Orientation.Horizontal, self)
        self.pitchLabel = BodyLabel('音调(--pitch=0%)', self)
        self.pitchSlider = Slider(Qt.Orientation.Horizontal, self)
        self.startButton = PrimaryPushButton(FIF.PLAY_SOLID, '开始合成', self)
        self.historyButton = TransparentToolButton(FIF.HISTORY, self)

        self.ttsThread = TTSThread(self)
        self.voiceThread = VoiceThread(self)
        self.stateToolTip = StateToolTip('合成中', '正在合成语音，请稍候...', self)

        self.__initWidgets()
        self.setLanguage()

        self.stateToolTip.setVisible(False)

    def __initWidgets(self):
        self.setObjectName("ConversionInterface")
        setFont(self.titleLabel, 20)

        self.rateSlider.setRange(-200, 200)
        self.volumeSlider.setRange(-200, 200)
        self.pitchSlider.setRange(-200, 200)
        self.rateSlider.setValue(0)
        self.volumeSlider.setValue(0)
        self.pitchSlider.setValue(0)

        self.__initLayout()
        self.__connectSignals()

    def __connectSignals(self):
        self.rateSlider.valueChanged.connect(self.onRateSliderChanged)
        self.volumeSlider.valueChanged.connect(self.onVolumeSliderChanged)
        self.pitchSlider.valueChanged.connect(self.onPitchSliderChanged)
        self.startButton.clicked.connect(self.onStartButtonClicked)
        self.historyButton.clicked.connect(lambda: signalBus.switchToSample.emit('historyInterface', {}))

        self.ttsThread.started.connect(self.onTtsThreadStarted)
        self.ttsThread.error.connect(lambda e: InfoBar.error('合成失败', e, duration=5000, parent=self.window()))
        self.ttsThread.finished.connect(self.onTtsThreadFinished)
        self.voiceThread.voiceChanged.connect(self.onVoiceChanged)

    def __initLayout(self):
        self.horizontalLayout.setContentsMargins(0, 0, 10, 10)
        self.horizontalLayout.addWidget(self.textEdit)

        self.verticalLayout.setAlignment(Qt.AlignmentFlag.AlignTop)
        self.verticalLayout.addWidget(self.titleLabel)
        self.verticalLayout.addWidget(HorizontalSeparator(self))
        self.verticalLayout.addWidget(self.cardListWidget)
        self.verticalLayout.addWidget(self.rateLabel)
        self.verticalLayout.addWidget(self.rateSlider)
        self.verticalLayout.addWidget(self.volumeLabel)
        self.verticalLayout.addWidget(self.volumeSlider)
        self.verticalLayout.addWidget(self.pitchLabel)
        self.verticalLayout.addWidget(self.pitchSlider)

        self.horizontalLayout_2.addWidget(self.startButton)
        self.horizontalLayout_2.addWidget(self.historyButton)
        self.verticalLayout.addLayout(self.horizontalLayout_2)

        self.horizontalLayout.addLayout(self.verticalLayout)
        self.horizontalLayout.setStretch(0, 4)
        self.horizontalLayout.setStretch(1, 2)

    def onVoiceChanged(self, voices: list):
        ix = 0
        for index, voice in enumerate(voices):
            item = TTSCard(self.cardListWidget)
            item.setUserData(voice)
            self.cardListWidget.addItem(item)
            if voice['ShortName'] == self.shortName:
                item.setChecked(True)
                ix = index
        self.cardListWidget.setCurrentRow(ix)

    def onRateSliderChanged(self, value: int):
        self.rateLabel.setText(f'语速(--rate={value}%)')

    def onVolumeSliderChanged(self, value: int):
        self.volumeLabel.setText(f'音量(--volume={value}%)')

    def onPitchSliderChanged(self, value: int):
        self.pitchLabel.setText(f'音调(--pitch={value}%)')

    def onStartButtonClicked(self):
        if self.startButton.text() == '终止合成':
            messageBox = MessageBox('警告', '是否要终止合成？', parent=self.window())
            if messageBox.exec():
                self.ttsThread.terminate()
        else:
            text = self.textEdit.toPlainText()
            voice = self.cardListWidget.currentItem().userData['ShortName']
            rate = self.rateSlider.value()
            volume = self.volumeSlider.value()
            pitch = self.pitchSlider.value()
            print('获取参数中。。。')

            if not text:
                InfoBar.error('错误', '请输入文本', duration=5000, parent=self.window())
                return
            elif not voice:
                InfoBar.error('错误', '请选择语音', duration=5000, parent=self.window())
                return
            print('参数获取成功，开始合成。。。')
            print('参数:', text[:20] + '...', voice, rate, volume, pitch)
            self.ttsThread.setData(text, voice, rate, volume, pitch)
            self.ttsThread.start()

    def onTtsThreadStarted(self):
        self.stateToolTip.setVisible(True)
        self.startButton.setText('终止合成')
        self.startButton.setIcon(Icon.STOP)

    def onTtsThreadFinished(self):
        self.stateToolTip.setVisible(False)
        self.startButton.setText('开始合成')
        self.startButton.setIcon(FIF.PLAY_SOLID)
        InfoBar.success('合成成功', '合成完成，请到临时保存目录查看', duration=5000, parent=self.window())

    def resizeEvent(self, event: QResizeEvent):
        self.stateToolTip.move(self.width() - self.stateToolTip.width() - 10, 50)
        super().resizeEvent(event)

    def setLanguage(self, language: str = 'zh-CN', shortName: str = None):
        self.titleLabel.setText(f'语音列表({TranslationDict.get(language, language)})')
        self.shortName = shortName
        self.cardListWidget.removeAllItems()
        self.voiceThread.setKey(language)
